package imgtagcounter;

import java.io.*;
import java.net.URL;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


    
    /**
 * This program is counting the number of img tags in the received list
 * of URLs.<br> The data is saved in a database and after each
 * program execution the content of the database is printed to stdout.
 * @author Oleg Ruchlis & Marcelo Korn
 */
public class ImgTagCounter {
    private static final String inputFilename = "a.txt";
    /**
     * main method of the program. receives a list of URLs through the command
     * line as first parameter.
     * @param args Contains path to the input file (args[0]). 
     */
    public static void main(String[] args) 
    {
        boolean userInputFile = true;
        // making sure user gave a valid input
        if(args.length == 0){
            userInputFile = false;
        }
        else{
            try{
                usageCheck(args);
            }catch(IllegalArgumentException ex){
                // printing error message + usage instructions
                System.out.println(ex.getMessage() + "Wrong usage!\n\rPlease"
                                   + " provide a valid file name that contains"
                                   + " URLs to check.");
                // closing the program
                System.exit(1);
            }
        }

        // initiating reader and writer object instances
        UserInputReader reader = null;
        UserOutputWriter writer = null;
        // will contain the current checked URL
        String urlAddress = "";
        
        // will contain the number of images for current URL.
        int numberOfImages = 0;
        
        //initiating instance of the reader.
        try {
            // checking if user provided an input file name.
            if(!userInputFile)
                reader = new UserInputReader(inputFilename); 
            else
                reader = new UserInputReader(args[0]);
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
            System.exit(1);
        }
        
        DatabaseUrl db=null;        
        try {
            // initinaning an instance of the database named "Statistics".
            db = new DatabaseUrl("Statistics");
            // connecting to Statistics database
            db.connect();
        } catch (IOException ex) {
            System.out.println("\r\nError occured while openning database: "
                               + ex.getMessage());
            System.exit(1);
        } catch (ClassNotFoundException ex) {
            System.out.println("\r\nError type: "+ ex.getMessage() +
                              "with local error:" +ex.getLocalizedMessage());
            System.exit(1);
        } catch(SQLException ex){
            System.out.println("Fatal SQL error occured: " + ex.getSQLState() 
                               + "\r\n" + ex.getMessage());
            System.exit(1);
        }
        
        // reading url's from user's input (stored in the reader instance).
        while((urlAddress = reader.getNextElement()) != null){
            try {
                // counting tags in current URL
                numberOfImages = countImgTags(urlAddress);               
            } catch (Exception ex) {
                // printing the error occured while trying to count img tags.
                System.out.println(ex.getMessage());
                // skipping the writing to DB sience there is no valid data.
                continue;
            }
            // storing the results to the database.
             db.saveRecord(urlAddress,numberOfImages);
        }
        
        
        List<ListEntry> listEntries;
        try {
            // receiving a list of all entries in the database
            listEntries = db.getListEntries();
            // initiating the writer and writing the entries to the stdout.
            writer = new UserOutputWriter(listEntries);
        } catch (SQLException ex) {
            System.out.println("Error: " + ex.getMessage() + "\r\n" 
                               + "Couldn't retrieve list of entries in "
                               + "the database."); 
        }
        
        
        // disconnecting from the database.
         db.disconnect();
    }
/**
     * Counting all img tags in the recieved URL
     * @param address URL of the site to count img tags in.
     * @return The number of img tags found at the URL received.
     * @throws Exception re-throws the message from the various IOExceptions
     *         that could have occurred while opening the different streams.
     */
    private static int countImgTags(String address) throws Exception{
        int counter = 0;    // img tags counter
        String line = null; // the current line in the html
        
        // creating a url instance for streaming
        URL url = null;
        try {
            url = new URL(address);
        } catch (IOException ex) {
            throw new IOException("Couldn't open: " + address);
        }
        
        // creating a stream from the url.
        InputStream input = null;
        try {
            input = url.openStream();
        } catch (IOException ex) {
            throw new IOException("Couldn't open stream from: "+url.toString());
        }
        
        // enabling read line by line.
        DataInputStream in = new DataInputStream(input);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        
        try {
            // reading line by line and looking for <img..> tags
            while ((line = br.readLine()) != null){
                if(line.contains("<img")){
                    // counting all img tags in the same line.
                    counter += line.split("<img").length - 1;
                }
            }
        } catch (IOException ex) {
            throw new IOException("Failed while reading a line from url: " + 
                                  url.toString());
        }
        
        return(counter);
    }
    
    /**
     * Checking the correctness of the input from the user <br>
     * We want to make sure user gave us a valid path of the input file
     * at args[0].
     * @param inArgs Arguments received from the user.
     */
    private static void usageCheck(String[] inArgs) throws IllegalArgumentException
    {
        // cehcking that an argument exists
        if(inArgs.length == 1)
        {
            // checking for file existence
            File inputFile = new File(inArgs[0]);
            if(inputFile.exists())
                return;
            throw new IllegalArgumentException("Error: Wrong file name or path.");
        }
    
        // throwing illegal usage, wrong argument.
        throw new IllegalArgumentException("Error: invalid arguments usage.");
    }
}
